﻿using System;
using System.Collections.Generic;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using Sinacor.Infra.Service.Common;
using Sinacor.Infra.Service.Validation;
using Sinacor.Servico.Bovespa.Contabil.ResourceAccess;

namespace Sinacor.Servico.Bovespa.Contabil.BusinessLogic
{
    /// <summary>
    /// BusinessLogic Class - EventoContabil
    /// </summary>
    public class EventoContabil : BaseBusinessLogic
    {
        #region Métodos Públicos

        /// <summary>
        /// Serviço irá alterar o EventoContabil informado como parâmetro.
        /// </summary>
        /// <param name="entity">BusinessEntity.EventoContabil</param>
        public void AlterarEventoContabil(BusinessEntity.EventoContabil entity)
        {
            if (entity == null)
                throw new BusinessException(109194);

            this.ValidarEventoContabil(entity);

            BusinessEntity.Parameter.FiltroEventoContabil filtroEventoContabil = new BusinessEntity.Parameter.FiltroEventoContabil();
            filtroEventoContabil.Descricao = entity.Descricao;

            List<BusinessEntity.EventoContabil> enventoContabilList = this.ConsultarEventosContabeis(filtroEventoContabil);

            if (enventoContabilList.Count > 0)
            {
                if(enventoContabilList[0].Codigo != entity.Codigo) 
                    throw new BusinessException(109193);
            }

            new ResourceAccess.EventoContabil().AlterarEventoContabil(entity);            
        }

        /// <summary>
        /// Serviço irá alterar uma coleção de EventosContabeis informados como parâmetro.
        /// </summary>
        /// <param name="entityList">Lista de objetos do tipo BusinessEntity.EventoContabil</param>
        public void AlterarEventosContabeis(List<BusinessEntity.EventoContabil> entityList)
        {
            foreach (BusinessEntity.EventoContabil entity in entityList)
                this.AlterarEventoContabil(entity);
        }

        /// <summary>
        /// Serviço irá Consultar uma lista de EventosContabeis, utilizando o parâmetro informado.
        /// </summary>
        /// <param name="parameter">BusinessEntity.Parameter.FiltroEventoContabil</param>
        /// <returns>Lista de objetos do tipo BusinessEntity.EventoContabil</returns>
        public List<BusinessEntity.EventoContabil> ConsultarEventosContabeis(BusinessEntity.Parameter.FiltroEventoContabil parameter)
        {
            return new ResourceAccess.EventoContabil().ConsultarEventosContabeis(parameter);
        }

        /// <summary>
        /// Serviço irá excluir o EventoContabil informado como parâmetro.
        /// </summary>
        /// <param name="parameter">BusinessEntity.Parameter.FiltroEventoContabilChave</param>
        public void ExcluirEventoContabil(BusinessEntity.Parameter.FiltroEventoContabilChave parameter)
        {
            if (parameter == null)
                throw new BusinessException(109200);

            ResourceAccess.EventoContabil eventoContabil = new ResourceAccess.EventoContabil();

            if (eventoContabil.VerificarDependenciaMovimentacaoContabil(parameter))
                throw new BusinessException(109201);
            else
            {
                if (eventoContabil.VerificarDependenciaContasContabeis(parameter))
                    throw new BusinessException(109202);
                else
                {
                    if (eventoContabil.VerificarDependenciaDespesasNota(parameter))
                        throw new BusinessException(109203);
                    else
                    {
                        if (eventoContabil.VerificarDependenciaMercadoNatureza(parameter))
                            throw new BusinessException(109204);
                        else
                            eventoContabil.ExcluirEventoContabil(parameter);
                    }
                }
            }   
        }

        /// <summary>
        /// Serviço irá excluir uma coleção de Eventos Contabeis informados como parâmetro.
        /// </summary>
        /// <param name="parameterList">Lista de objetos do tipo BusinessEntity.Parameter.FiltroEventoContabilChave</param>
        public void ExcluirEventosContabeis(List<BusinessEntity.Parameter.FiltroEventoContabilChave> parameterList)
        {
            foreach (BusinessEntity.Parameter.FiltroEventoContabilChave parameter in parameterList)
                this.ExcluirEventoContabil(parameter); 
        }

        /// <summary>
        /// Serviço irá incluir o EventoContabil informado como parâmetro.
        /// </summary>
        /// <param name="entity">BusinessEntity.EventoContabil</param>
        public void IncluirEventoContabil(BusinessEntity.EventoContabil entity)
        {
            if (entity == null)
                throw new BusinessException(109195);
            else
            {
                if (entity.Codigo < 1)
                    throw new BusinessException(109196);
                else
                {
                    BusinessEntity.Parameter.FiltroEventoContabil filtroEventoContabil = new BusinessEntity.Parameter.FiltroEventoContabil();
                    filtroEventoContabil.Codigo = entity.Codigo;

                    if (this.ConsultarEventosContabeis(filtroEventoContabil).Count > 0)
                        throw new BusinessException(109198);
                    else
                    {
                        this.ValidarEventoContabil(entity);

                        filtroEventoContabil.Codigo = null;
                        filtroEventoContabil.Descricao = entity.Descricao;

                        if (this.ConsultarEventosContabeis(filtroEventoContabil).Count > 0)
                            throw new BusinessException(109340);

                        new ResourceAccess.EventoContabil().IncluirEventoContabil(entity);
                    } 
                }
            }
        }

        /// <summary>
        /// Serviço irá incluir uma coleção de Eventos Contabeis informados como parâmetro.
        /// </summary>
        /// <param name="entityList">Lista de objetos do tipo BusinessEntity.EventoContabil</param>
        public void IncluirEventosContabeis(List<BusinessEntity.EventoContabil> entityList)
        {
            foreach (BusinessEntity.EventoContabil entity in entityList)
                this.IncluirEventoContabil(entity);
        }

        /// <summary>
        /// Serviço irá excluir/incluir/alterar os objetos EventoContabil informados como parâmetro.
        /// </summary>
        /// <param name="exclusaoList">Lista de objetos BusinessEntity.Parameter.FiltroEventoContabilChave</param>
        /// <param name="inclusaoList">Lista de objetos BusinessEntity.EventoContabil</param>
        /// <param name="alteracaoList">Lista de objetos BusinessEntity.EventoContabil</param>
        public void ExecutarTransacoesEventoContabil(   List<BusinessEntity.Parameter.FiltroEventoContabilChave> exclusaoList,
                                                        List<BusinessEntity.EventoContabil> inclusaoList, 
                                                        List<BusinessEntity.EventoContabil> alteracaoList)
        {
            this.ExcluirEventosContabeis(exclusaoList);
            this.IncluirEventosContabeis(inclusaoList);
            this.AlterarEventosContabeis(alteracaoList);
        }

        /// <summary>
        /// Serviço irá Obter o EventoContabil informado como parâmetro.
        /// </summary>
        /// <param name="parameter">BusinessEntity.Parameter.FiltroEventoContabilChave</param>
        /// <returns>BusinessEntity.EventoContabil</returns>
        public BusinessEntity.EventoContabil ObterEventoContabil(BusinessEntity.Parameter.FiltroEventoContabilChave parameter)
        {
            BusinessEntity.Parameter.FiltroEventoContabil filtroEventoContabil = new BusinessEntity.Parameter.FiltroEventoContabil();
            filtroEventoContabil.Codigo = parameter.Codigo;

            List<BusinessEntity.EventoContabil> entityList = ConsultarEventosContabeis(filtroEventoContabil);

            if (entityList.Count > 0)
                return entityList[0];

            return new BusinessEntity.EventoContabil();
        }

        #endregion

        #region Métodos Privados

        /// <summary>
        /// Valida a entidade BusinessEntity.EventoContabil
        /// </summary>
        /// <param name="entity">BusinessEntity.EventoContabil</param>
        private void ValidarEventoContabil(BusinessEntity.EventoContabil entity)
        {
            SinacorValidation validation = new SinacorValidation();
            validation.Validate<BusinessEntity.EventoContabil>(entity);            
        }

        #endregion
    }
}
